package service;

import utils.DatabaseUtil;
import java.sql.*;
import java.util.*;

// 教室服务类，负责处理与教室相关的业务逻辑，与数据库进行交互
public class ClassroomService {

    /**
     * 获取所有教室
     * 黄嘉毅
     * 该方法从数据库中查询所有教室的信息，并以List<Map<String, Object>>的形式返回。
     * 数据库中的教室信息按教学楼（building）、楼层（floor）和教室号（room_number）排序。
     *
     * @return 包含所有教室信息的List，每个元素是一个Map，键为字段名，值为对应字段的值
     */
    public List<Map<String, Object>> getAllClassrooms() {
        List<Map<String, Object>> classrooms = new ArrayList<>();
        // SQL查询语句，选择classrooms表中的所有数据，并按building、floor和room_number排序
        String sql = "SELECT * FROM classrooms ORDER BY building, floor, room_number";

        try (Connection conn = DatabaseUtil.getConnection();
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery(sql)) {
            // 遍历结果集，将每一行数据转换为Map并添加到List中
            while (rs.next()) {
                Map<String, Object> classroom = new HashMap<>();
                classroom.put("id", rs.getInt("id"));
                classroom.put("roomNumber", rs.getString("room_number"));
                classroom.put("building", rs.getString("building"));
                classroom.put("floor", rs.getInt("floor"));
                classroom.put("capacity", rs.getInt("capacity"));
                classroom.put("type", rs.getString("type"));
                classroom.put("status", rs.getInt("status"));
                classroom.put("description", rs.getString("description"));
                classrooms.add(classroom);
            }
        } catch (SQLException e) {
            // 如果发生SQL异常，打印异常堆栈信息
            e.printStackTrace();
        }
        return classrooms;
    }

    /**
     * 获取可用教室
     * 该方法根据传入的星期几（weekday）和时间段（period），从数据库中查询出状态为可用（status = 1）
     * 且在该时间段内没有课程安排的教室信息，并以List<Map<String, Object>>的形式返回。
     * 数据库中的教室信息按教学楼（building）、楼层（floor）和教室号（room_number）排序。
     *
     * @param weekday 星期几，1 - 7代表周一到周日
     * @param period  时间段，例如1 - 12代表不同的课程时间段
     * @return 包含可用教室信息的List，每个元素是一个Map，键为字段名，值为对应字段的值
     */
    public List<Map<String, Object>> getAvailableClassrooms(int weekday, int period) {
        List<Map<String, Object>> classrooms = new ArrayList<>();
        // SQL查询语句，选择状态为1且不在指定时间段课程安排中的教室
        String sql = "SELECT c.* FROM classrooms c " +
                "WHERE c.status = 1 " +
                "AND c.id NOT IN (" +
                "   SELECT cs.classroom_id FROM course_schedules cs " +
                "   WHERE cs.weekday =? AND cs.period =?" +
                ") ORDER BY c.building, c.floor, c.room_number";

        try (Connection conn = DatabaseUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setInt(1, weekday);
            pstmt.setInt(2, period);
            ResultSet rs = pstmt.executeQuery();

            // 遍历结果集，将每一行数据转换为Map并添加到List中
            while (rs.next()) {
                Map<String, Object> classroom = new HashMap<>();
                classroom.put("id", rs.getInt("id"));
                classroom.put("roomNumber", rs.getString("room_number"));
                classroom.put("building", rs.getString("building"));
                classroom.put("floor", rs.getInt("floor"));
                classroom.put("capacity", rs.getInt("capacity"));
                classroom.put("type", rs.getString("type"));
                classrooms.add(classroom);
            }
        } catch (SQLException e) {
            // 如果发生SQL异常，打印异常堆栈信息
            e.printStackTrace();
        }
        return classrooms;
    }

    /**
     * 添加教室
     * 该方法向数据库中插入一条新的教室记录。
     *
     * @param building  教学楼名称
     * @param roomNumber 教室号
     * @param floor      楼层
     * @param capacity   教室容量
     * @param type       教室类型
     * @param status     教室状态
     * @return 如果插入成功返回true，否则返回false
     */
    public boolean addClassroom(String building, String roomNumber, int floor, int capacity, String type, int status) {
        // SQL插入语句，向classrooms表中插入新的教室记录
        String sql = "INSERT INTO classrooms (building, room_number, floor, capacity, type, status) " +
                "VALUES (?,?,?,?,?,?)";

        try (Connection conn = DatabaseUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setString(1, building);
            pstmt.setString(2, roomNumber);
            pstmt.setInt(3, floor);
            pstmt.setInt(4, capacity);
            pstmt.setString(5, type);
            pstmt.setInt(6, status);

            // 执行插入操作并返回结果，如果插入的行数大于0则表示成功
            return pstmt.executeUpdate() > 0;
        } catch (SQLException e) {
            // 如果发生SQL异常，打印异常堆栈信息并返回false
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 更新教室信息
     * 该方法根据传入的教学楼（building）和教室号（roomNumber），更新数据库中教室的楼层（floor）、容量（capacity）、类型（type）和状态（status）。
     *
     * @param building  教学楼名称
     * @param roomNumber 教室号
     * @param floor      新的楼层
     * @param capacity   新的教室容量
     * @param type       新的教室类型
     * @param status     新的教室状态
     * @return 如果更新成功返回true，否则返回false
     */
    public boolean updateClassroom(String building, String roomNumber, int floor, int capacity, String type, int status) {
        // SQL更新语句，更新classrooms表中指定教室的楼层、容量、类型和状态
        String sql = "UPDATE classrooms SET floor =?, capacity =?, type =?, status =? " +
                "WHERE building =? AND room_number =?";

        try (Connection conn = DatabaseUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setInt(1, floor);
            pstmt.setInt(2, capacity);
            pstmt.setString(3, type);
            pstmt.setInt(4, status);
            pstmt.setString(5, building);
            pstmt.setString(6, roomNumber);

            // 执行更新操作并返回结果，如果更新的行数大于0则表示成功
            return pstmt.executeUpdate() > 0;
        } catch (SQLException e) {
            // 如果发生SQL异常，打印异常堆栈信息并返回false
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除教室
     * 该方法根据传入的教学楼（building）和教室号（roomNumber），从数据库中删除对应的教室记录。
     *
     * @param building  教学楼名称
     * @param roomNumber 教室号
     * @return 如果删除成功返回true，否则返回false
     */
    public boolean deleteClassroom(String building, String roomNumber) {
        // SQL删除语句，从classrooms表中删除指定教学楼和教室号的记录
        String sql = "DELETE FROM classrooms WHERE building =? AND room_number =?";

        try (Connection conn = DatabaseUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setString(1, building);
            pstmt.setString(2, roomNumber);

            // 执行删除操作并返回结果，如果删除的行数大于0则表示成功
            return pstmt.executeUpdate() > 0;
        } catch (SQLException e) {
            // 如果发生SQL异常，打印异常堆栈信息
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 获取单个教室信息
     * 该方法根据传入的教学楼（building）和教室号（roomNumber），从数据库中查询对应的教室信息，并以Map<String, Object>的形式返回。
     *
     * @param building  教学楼名称
     * @param roomNumber 教室号
     * @return 包含教室信息的Map，如果未找到则返回null
     */
    public Map<String, Object> getClassroomById(String building, String roomNumber) {
        // SQL查询语句，选择classrooms表中指定教学楼和教室号的记录
        String sql = "SELECT * FROM classrooms WHERE building =? AND room_number =?";

        try (Connection conn = DatabaseUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setString(1, building);
            pstmt.setString(2, roomNumber);
            ResultSet rs = pstmt.executeQuery();

            if (rs.next()) {
                Map<String, Object> classroom = new HashMap<>();
                classroom.put("building", rs.getString("building"));
                classroom.put("roomNumber", rs.getString("room_number"));
                classroom.put("floor", rs.getInt("floor"));
                classroom.put("capacity", rs.getInt("capacity"));
                classroom.put("type", rs.getString("type"));
                classroom.put("status", rs.getInt("status"));
                classroom.put("description", rs.getString("description"));
                return classroom;
            }
        } catch (SQLException e) {
            // 如果发生SQL异常，打印异常堆栈信息
            e.printStackTrace();
        }
        return null;
    }
}
